﻿'use strict';

if (zxcv && !zxcv.raw.Graphics) {
    if (window.WebGLRenderingContext) {
        zxcv.raw.Graphics = function (canvas) {
            var i, length,
                gl = null,
                glNames = ['webgl', 'experimental-webgl', 'webkit-3d', 'moz-webgl'],
                options = { alpha: false, depth: false, stencil: false };

            // WebGL Context를 찾습니다.
            for (i = 0, length = glNames.length; i < length; i++) {
                try {
                    gl = canvas.getContext(glNames[i], options);
                }
                catch (e) { }
                if (gl)
                    break;
            }
            if (gl == null)
                throw new Error('start failed. WebGL not initialized.');

            // 찾은 WebGL을 초기화합니다.
            gl.clearColor(0.392, 0.584, 0.929, 1.0);
            gl.disable(gl.CULL_FACE);
            gl.disable(gl.DEPTH_TEST);
            gl.viewport(0, 0, canvas.width, canvas.height);
            
            this.gl = gl;
            this.canvas = canvas;
            this.buffers = [
                gl.createBuffer(), // 0: Positions
                gl.createBuffer(), // 1: Textures
                gl.createBuffer(), // 2: Colors
            ];
            this.transforms = [
                mat4.create(), // 0: World/Model
                mat4.create(), // 1: Projection * View    
            ];

            this.aspect = canvas.width / canvas.height;
            this.fov = Math.PI * 0.25;
            this.cameraDistance = Math.tan((Math.PI - this.fov) * 0.5) * canvas.width * 0.5 / this.aspect;
            
            this.begin = function () {
                var gl = this.gl,
                    canvas = this.canvas,
                    tm = this.transforms;

                mat4.identity(tm[0]);
                mat4.perspective(45, this.aspect, 0.1, 10000.0, tm[1]);
                mat4.translate(tm[1], [0, 0, -this.cameraDistance]);
                mat4.rotate(tm[1], Math.PI, [1.0, 0, 0]);
                mat4.translate(tm[1], [-canvas.width * 0.5, -canvas.height * 0.5, 0]);
                
                var m = tm[1];
                alert(m[0]  + ',' + m[1]  + ',' + m[2]  + ',' + m[3] + '\n' +
                      m[4]  + ',' + m[5]  + ',' + m[6]  + ',' + m[7] + '\n' +
                      m[8]  + ',' + m[9]  + ',' + m[10] + ',' + m[11] + '\n' +
                      m[12] + ',' + m[13] + ',' + m[14] + ',' + m[15]);

                gl.clear(gl.COLOR_BUFFER_BIT);
            }

            this.end = function () {
                this.gl.flush();
            }

            this.draw = function (texture, x, y, originX, originY, sourceRectangle) {
                if (!texture || !texture.status == zxcv.ASSET_LOADED)
                    return;

                var gl = this.gl,
                    buffers = this.buffers;
                    
                x = x || 0;
                y = y || 0;
                x -= originX || 0;
                y -= originY || 0;
                sourceRectangle = sourceRectangle || [0, 0, texture.width, texture.height];
                
                var w = sourceRectangle[2],
                    h = sourceRectangle[3],
                    tw = texture.width,
                    th = texture.height,
                    sl = sourceRectangle[0],
                    st = sourceRectangle[1],
                    sr = sl + w,
                    sb = st + h,
                    pos = [
                        x,     y, 0,
                        x + w, y, 0,
                        x,     y + h, 0,
                        x + w, y + h, 0,
                    ],
                    uv = [ // convert to OpenGL texture coordinate.
                        sl / tw, 1.0 - st / th,
                        sr / tw, 1.0 - st / th,
                        sl / tw, 1.0 - sb / th,
                        sr / tw, 1.0 - sb / th,
                    ];

                gl.enable(gl.BLEND);
                gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
                gl.blendEquation(gl.FUNC_ADD);

                gl.useProgram(program.raw);
                gl.enableVertexAttribArray(program.attributes.VPosition);
                gl.enableVertexAttribArray(program.attributes.VTexture1);
                
                gl.bindBuffer(gl.ARRAY_BUFFER, buffers[0]);
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(pos), gl.DYNAMIC_DRAW);
                gl.vertexAttribPointer(program.attributes.VPosition, 3, gl.FLOAT, false, 0, 0);

                gl.bindBuffer(gl.ARRAY_BUFFER, buffers[1]);
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(uv), gl.DYNAMIC_DRAW);
                gl.vertexAttribPointer(program.attributes.VTexture1, 2, gl.FLOAT, false, 0, 0);

                gl.activeTexture(gl.TEXTURE0);
                gl.bindTexture(gl.TEXTURE_2D, texture.raw);
                gl.uniform1i(program.uniforms.Sampler1, 0);

                gl.uniformMatrix4fv(program.uniforms.World,      false, this.transforms[0]);
                gl.uniformMatrix4fv(program.uniforms.Projection, false, this.transforms[1]);
                gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
                gl.bindBuffer(gl.ARRAY_BUFFER, null);
            }
            
            this.drawDebugCircle = function (x, y, radius, color) {
            }
        }
    }
    else ////////////////////////////////////////////////////////////////////////////////////////////////////
    {
        zxcv.raw.Graphics = function (canvas)
        {
        };
    }
}